package com.gbase8c.dmt.db.opengauss;

import com.gbase8c.dmt.db.object.SequenceObject;
import com.gbase8c.dmt.db.object.TableObject;
import com.gbase8c.dmt.model.migration.dto.DataSourceDto;
import com.gbase8c.dmt.model.migration.dto.SequenceDto;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Slf4j
// todo 没有具体实现
public class SequenceObjectImpl extends MetaImpl implements SequenceObject {

    protected TableObject tableObject;

    public SequenceObjectImpl(DataSourceDto dataSourceDto) {
        super(dataSourceDto);
    }

    @Override
    public List<String> getNames(Map<String, Object> params) {
        String schema = (String)params.get("schema");
        String sql = "select sequence_name as sequenceName from all_sequences where sequence_name not in('LOGMNR_DIDS$'," +
                "'LOGMNR_EVOLVE_SEQ$','LOGMNR_SEQ$','LOGMNR_UIDS$','MVIEW$_ADVSEQ_GENERIC','MVIEW$_ADVSEQ_ID','ROLLING_EVENT_SEQ$') and sequence_owner = ?";
        List<String> sequenceNames = query(sql, new ColumnListHandler<String>(), schema);
        return sequenceNames;
    }

    @Override
    public SequenceDto get(String name, Map<String, Object> params) {
        String schema = (String)params.get("schema");
        String sql = "SELECT sequence_owner as schema, sequence_name as sequenceName,min_value as minValue,max_value as maxValue,increment_by as incrementBy, cycle_flag as cycle,cache_size as cacheSize, last_number as lastNumber FROM all_sequences where sequence_owner = ? and sequence_name = ?";
        SequenceDto dto = query(sql, new BeanHandler<>(SequenceDto.class), schema, name);
        return dto;
    }

    @Override
    public SequenceDto convert(SequenceDto sequenceDto, Map<String, Object> params) {
        String incrementBy = sequenceDto.getIncrementBy();
        String lastNumber = sequenceDto.getLastNumber();
//        Long temp = Long.valueOf(incrementBy) + Long.valueOf(lastNumber);
        Long temp = Long.valueOf(lastNumber);
        String startWith = String.valueOf(temp);
        sequenceDto.setStartWith(startWith);
        sequenceDto.setConvertible(Boolean.TRUE);

        if (sequenceDto.getConvertible()){
            sequenceDto.setConvertMsg("已完成");
        } else {
            sequenceDto.setConvertMsg("失败");
        }

        return sequenceDto;
    }

    @Override
    public String sql(SequenceDto sequenceDto, Map<String, Object> params) {
        String sequenceName = sequenceDto.getName();
        String tarSchema = sequenceDto.getTarSchema();
        ////创建序列
        //create sequence seq_user_camera_version increment by 1 minvalue 1 no maxvalue start with 1 cache 20 cycle owned by none;

        boolean preserveCase = sequenceDto.getTask().getMigrateConfig().isPreserveCase();

        StringBuilder stringBuilder = new StringBuilder();
//        stringBuilder.append("drop sequence ").append(schema).append(".").append(sequenceName).append(";");

        stringBuilder.append(" create sequence ")
                .append(wrap(tarSchema, true))
                .append(".")
                .append(wrap(sequenceName, preserveCase))
                .append(" increment by ")
                .append(sequenceDto.getIncrementBy());

        if (!("-999999999999999999999999999".equals(sequenceDto.getMinValue()))) {
            stringBuilder.append(" minvalue ").append(sequenceDto.getMinValue());
        }
        // 最大值为9223372036854775807
        // value "9223372036854775808" is out of range for type bigint Query:
        // create sequence test_dmt.testmaxvalue increment by 1 minvalue 1 maxvalue 9223372036854775808 start with 1 cache 20 Parameters: []
        if (new BigDecimal(sequenceDto.getMaxValue()).compareTo(new BigDecimal(9223372036854775807L)) > 0) {
            stringBuilder.append(" maxvalue ").append("9223372036854775807");
        } else {
            stringBuilder.append(" maxvalue ").append(sequenceDto.getMaxValue());
        }
//        if (!("9999999999999999999999999999".equals(sequenceDto.getMaxValue()))) {
//            stringBuilder.append(" maxvalue ").append(sequenceDto.getMaxValue());
//        }
        stringBuilder.append(" start with ").append(sequenceDto.getStartWith());

        if (!("0".equals(sequenceDto.getCacheSize())))
        {
            stringBuilder.append(" cache ").append(sequenceDto.getCacheSize());
        }

        if ("Y".equals(sequenceDto.getCycle())){
            stringBuilder.append(" cycle");
        }

        log.info(stringBuilder.toString());
        return stringBuilder.toString();
    }

    @Override
    public List<SequenceDto> getSequenceDtos(String schema) {
        Map<String, Object> params = Maps.newHashMap();
        params.put("schema", schema);

        List<SequenceDto>  sequenceDtos = Lists.newArrayList();
        StringBuilder sql = new StringBuilder("select sequence_owner as schema, sequence_name as sequenceName from all_sequences where sequence_name not in('LOGMNR_DIDS$'," +
                "'LOGMNR_EVOLVE_SEQ$','LOGMNR_SEQ$','LOGMNR_UIDS$','MVIEW$_ADVSEQ_GENERIC','MVIEW$_ADVSEQ_ID','ROLLING_EVENT_SEQ$') and sequence_owner = ?");
        sequenceDtos = query(sql.toString(), new BeanListHandler<>(SequenceDto.class),schema);
        return sequenceDtos;
    }


}
